package com.yule.controller.system;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yule.config.DynamicDataSourceContext;
import com.yule.controller.BaseController;
import com.yule.mq.producer.SystemLogProducer;
import com.yule.query.Query;
import com.yule.system.home.*;
import com.yule.system.model.*;
import com.yule.vo.LogModuleVo;
import com.yule.vo.LogOperateVo;
import com.yule.utils.UserUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/system/user")
public class UserController extends BaseController {

    @Autowired
    private SystemUserHome systemUserHome;

    @Autowired
    private SystemDeptHome systemDeptHome;

    @Autowired
    private SystemDutyHome systemDutyHome;

    @Autowired
    private SystemUserRoleHome systemUserRoleHome;

    @Autowired
    private SystemRoleHome systemRoleHome;

    @Autowired
    private SystemCustomHome systemCustomHome;

    @Autowired
    private CorpInfoHome corpInfoHome;

    @Autowired
    private SystemLogProducer systemLogProducer;

    @RequestMapping("/list")
    public ModelAndView list(PageInfo page, Query query){
        ModelAndView mav = new ModelAndView();
        Query q = Query.getInstance(query);
        SystemUser user = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType(user.getCorpLoginName());
        PageHelper.startPage(page.getPageNum(), 10);
        SystemUserExample systemUserExample = new SystemUserExample();
        SystemUserExample.Criteria criteria = systemUserExample.createCriteria();
        criteria.andIsDelEqualTo(false).andCorpIdEqualTo(user.getCorpId());
        if (StringUtils.isNotEmpty(q.getName())) {
            criteria.andNameLike(q.getName());
        }
        systemUserExample.setOrderByClause("id asc");
        List<SystemUser> list = systemUserHome.findList(systemUserExample);
        for (SystemUser systemUser : list) {
            SystemDept systemDept = systemDeptHome.findOne(systemUser.getDeptId());
            systemUser.setSystemDept(systemDept);
            SystemDuty systemDuty = systemDutyHome.findOne(systemUser.getDutyId());
            systemUser.setSystemDuty(systemDuty);
            List<SystemRole> systemRoleList = systemCustomHome.findRoleListByUserId(systemUser);
            systemUser.setSystemRoleList(systemRoleList);
        }
        PageInfo pageInfo = new PageInfo(list);
        mav.addObject("page", pageInfo);
        mav.addObject("query", query);
        mav.setViewName("system/user/list");
        return mav;
    }

    @RequestMapping("/add")
    public ModelAndView add(){
        ModelAndView mav = new ModelAndView();
        SystemUser user = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType(user.getCorpLoginName());
        SystemDeptExample systemDeptExample = new SystemDeptExample();
        systemDeptExample.createCriteria().andIsDelEqualTo(false).andCorpIdEqualTo(user.getCorpId());
        List<SystemDept> deptList = systemDeptHome.findList(systemDeptExample);
        mav.addObject("deptList", deptList);
        SystemDutyExample systemDutyExample = new SystemDutyExample();
        systemDutyExample.createCriteria().andIsDelEqualTo(false).andCorpIdEqualTo(user.getCorpId());
        List<SystemDuty> dutyList = systemDutyHome.findList(systemDutyExample);
        mav.addObject("dutyList", dutyList);
        mav.setViewName("system/user/add");
        return mav;
    }

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(@ModelAttribute("model") SystemUser model){
        SystemUser user = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType("default");
        CorpInfo corpInfo = corpInfoHome.findOne(user.getCorpId());
        DynamicDataSourceContext.setDBType(user.getCorpLoginName());
        SystemUserExample systemUserExample = new SystemUserExample();
        SystemUserExample.Criteria criteria = systemUserExample.createCriteria();
        criteria.andCorpIdEqualTo(user.getCorpId());
        List<SystemUser> systemUserList = systemUserHome.findList(systemUserExample);
        if (systemUserList.size() < corpInfo.getUseNum()) {
            model.setUsername(corpInfo.getLoginCorpName() + "_" + model.getUsername());
            model.setCorpLoginName(user.getCorpLoginName());
            model.setCorpId(user.getCorpId());
            model.setSalt("abcd");
            model.setPassword(new SimpleHash("md5","1", ByteSource.Util.bytes("abcd"),2).toString());
            model.setIsDel(false);
            model.setIsEnable(true);
            model.setIsSuper(false);
            systemUserHome.save(model);
            systemLogProducer.sendLog(new SystemLog(user, LogOperateVo.add.getKey(), LogModuleVo.system_user.getKey(), model.getName(), new Date()));
        }
        return "redirect:/system/user/list";
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
    public ModelAndView edit(@PathVariable int id){
        ModelAndView mav = new ModelAndView();
        SystemUser systemUser = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType(systemUser.getCorpLoginName());
        SystemUser user = systemUserHome.findOne(id);
        mav.addObject("model", user);
        SystemDeptExample systemDeptExample = new SystemDeptExample();
        systemDeptExample.createCriteria().andIsDelEqualTo(false).andCorpIdEqualTo(user.getCorpId());
        List<SystemDept> deptList = systemDeptHome.findList(systemDeptExample);
        mav.addObject("deptList", deptList);
        SystemDutyExample systemDutyExample = new SystemDutyExample();
        systemDutyExample.createCriteria().andIsDelEqualTo(false).andCorpIdEqualTo(user.getCorpId());
        List<SystemDuty> dutyList = systemDutyHome.findList(systemDutyExample);
        mav.addObject("dutyList", dutyList);
        mav.setViewName("system/user/edit");
        return mav;
    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(@ModelAttribute("model") SystemUser model){
        SystemUser user = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType(user.getCorpLoginName());
        systemUserHome.update(model);
        systemLogProducer.sendLog(new SystemLog(user, LogOperateVo.edit.getKey(), LogModuleVo.system_user.getKey(), model.getName(), new Date()));
        return "redirect:/system/user/list";
    }

    @RequestMapping(value = "/deletes/{ids}", method = RequestMethod.GET)
    public String delete(@PathVariable int[] ids) {
        SystemUser systemUser = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType(systemUser.getCorpLoginName());
        for (int id : ids) {
            if (id != 1) {
                systemUserHome.delete(id);
                systemLogProducer.sendLog(new SystemLog(systemUser, LogOperateVo.delete.getKey(), LogModuleVo.system_user.getKey(),id + "", new Date()));
            }
        }
        return "redirect:/system/user/list/";
    }

    @RequestMapping(value = "/role_set/{id}", method = RequestMethod.GET)
    public ModelAndView roleSet(@PathVariable int id) {
        SystemUser systemUser = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType(systemUser.getCorpLoginName());
        ModelAndView mav = new ModelAndView();
        SystemUser user = systemUserHome.findOne(id);
        user.setSystemDept(systemDeptHome.findOne(user.getDeptId()));
        user.setSystemDuty(systemDutyHome.findOne(user.getDutyId()));
        mav.addObject("model", user);
        SystemRoleExample systemRoleExample = new SystemRoleExample();
        systemRoleExample.createCriteria().andCorpIdEqualTo(user.getCorpId()).andIsDelEqualTo(false);
        List<SystemRole> systemRoleList = systemRoleHome.findList(systemRoleExample);
        SystemUserRoleExample systemUserRoleExample = new SystemUserRoleExample();
        systemUserRoleExample.createCriteria().andCorpIdEqualTo(user.getCorpId()).andUserIdEqualTo(id);
        List<SystemUserRole> systemUserRoleList = systemUserRoleHome.findList(systemUserRoleExample);
        for (SystemRole systemRole : systemRoleList) {
            for (SystemUserRole systemUserRole : systemUserRoleList) {
                if (systemRole.getId() == systemUserRole.getRoleId()) {
                    systemRole.setIsCheck(true);
                }
            }
        }
        mav.addObject("systemRoleList", systemRoleList);
        mav.setViewName("system/user/role_set");
        return mav;
    }

    @RequestMapping(value = "/role_set", method = RequestMethod.POST)
    public String roleSet(@ModelAttribute("model") SystemUserRole model){
        SystemUser user = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType(user.getCorpLoginName());
        SystemUserRoleExample systemUserRoleExample = new SystemUserRoleExample();
        systemUserRoleExample.createCriteria().andCorpIdEqualTo(user.getCorpId()).andUserIdEqualTo(model.getUserId());
        systemUserRoleHome.delete(systemUserRoleExample);
        for (Integer roleId : model.getRoleIds()) {
            SystemUserRole systemUserRole = new SystemUserRole();
            systemUserRole.setCorpId(user.getCorpId());
            systemUserRole.setUserId(model.getUserId());
            systemUserRole.setRoleId(roleId);
            systemUserRoleHome.save(systemUserRole);
        }
        return "redirect:/system/user/list";
    }

    @ResponseBody
    @RequestMapping(value = "/checkUserName/{name}", method = RequestMethod.GET)
    public JSONObject checkName(@PathVariable String name) {
        SystemUser user = UserUtils.getUser(SecurityUtils.getSubject().getPrincipal());
        DynamicDataSourceContext.setDBType("default");
        CorpInfo corpInfo = corpInfoHome.findOne(user.getCorpId());
        JSONObject jObject = new JSONObject();
        SystemUserExample systemUserExample = new SystemUserExample();
        SystemUserExample.Criteria criteria = systemUserExample.createCriteria();
        criteria.andCorpIdEqualTo(user.getCorpId());
        if (StringUtils.isNotEmpty(name)) {
            criteria.andUsernameEqualTo(corpInfo.getLoginCorpName() + "_" + name);
        }
        DynamicDataSourceContext.setDBType(user.getCorpLoginName());
        List<SystemUser> list = systemUserHome.findList(systemUserExample);
        systemUserExample.clear();
        criteria.andCorpIdEqualTo(user.getCorpId());
        List<SystemUser> systemUserList = systemUserHome.findList(systemUserExample);
        if (list.size() > 0 || systemUserList.size() >= corpInfo.getUseNum()) {
            jObject.put("rs", false);
        } else {
            jObject.put("rs", true);
        }
        return jObject;
    }
    
	@RequestMapping(value="password", method=RequestMethod.GET)
	public ModelAndView password() {
		ModelAndView mv = new ModelAndView();
		SystemUser user = UserUtils.setDBType();
		if (user != null) {
			mv.addObject("model", systemUserHome.findOne(user.getId()));
			mv.setViewName("system/user/password");
		} else {
			mv.setViewName("redirect:/login");
		}
		return mv;
	}

	@ResponseBody
	@RequestMapping(value="password", method=RequestMethod.POST)
	public String password(@RequestBody JSONObject jsonObject) {
		Map<String,Object> map = new HashMap<>();
		SystemUser user = UserUtils.setDBType();
		if (user != null) {
			SystemUser model = systemUserHome.findOne(user.getId());
			if(StringUtils.equals(model.getPassword(), new SimpleHash("md5", jsonObject.getString("oldPassword"), ByteSource.Util.bytes("abcd"),2).toString())) {
				model.setPassword(new SimpleHash("md5", jsonObject.getString("newPassword"), ByteSource.Util.bytes("abcd"),2).toString());
				systemUserHome.update(model);
				map.put("status", "login");
			}else {
				map.put("status", "incorrect");
			}
		} else {
			map.put("status", "login");
		}
		return JSON.toJSONString(map, SerializerFeature.WriteMapNullValue, SerializerFeature.DisableCircularReferenceDetect);
	}

}
